/***************************************************************************
                          PlayState.cpp  -  description
                             -------------------
    begin                : October 29 2009
    copyright            : Copyright 2009, ACKERMANN Thibaut
    email                : tackerma@edu.univ-fcomte.fr
    website              : http://code.google.com/p/nover-project/
    license              : GNU GPL v3
 ***************************************************************************/
/* *************************************************************************
 *  This file is part of NOver-Project.
 *  
 *  NOver-Project is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *  
 *  NOver-Project is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with NOver-Project.  If not, see <http://www.gnu.org/licenses/>.
 * *************************************************************************/


#include "PlayState.hpp"


int MouseLeftDownX;
int MouseLeftDownY;
bool mouse_down;
bool click;

float elapsed_time;
float total_time;
std::string lastContinent;

bool PlayStateCallBack(const irr::SEvent& event)
{
	PlayState* ps = dynamic_cast<PlayState*>(StateMgr::Instance()->getCurrentGameState());
	
	// oops !
	if(!ps)
		return false;
	
	
	// evenements interface
	if (event.EventType == EET_GUI_EVENT)
	{
		if(event.GUIEvent.EventType == EGET_COMBO_BOX_CHANGED)
		{
			if(event.GUIEvent.Caller->getID() == id_ContinentCombo)
			{
				gui::IGUIComboBox* combo = dynamic_cast<gui::IGUIComboBox*>(event.GUIEvent.Caller);
				
				if(!combo)
					throw MyException("Erreur de cast interne", __FILE__, __LINE__);
				
				ContinentView* cv = dynamic_cast<ContinentView*>(ps->currentView);
				
				if(!cv)
					throw MyException("Erreur de cast interne", __FILE__, __LINE__);
				
				
				// inexplicable ...
				int i = combo->getSelected();
				
				//cout << cv->getCarteFilename() << " et "<< DataMgr::Instance()->getContinentAt(i)->map << endl;
				
				// si c'est le continent courant, on ne le recharge pas.
				if(cv->getCarteFilename().compare(DataMgr::Instance()->getContinentAt(i)->map) == 0)
					return true;
				
				// c'est pour nous.
				delete ps->currentView;
				ps->currentView = 0;
				
				// on nettoie
				StateMgr::Instance()->getSceneMgr()->clear();
				StateMgr::Instance()->getGuiEnv()->clear();
				
				lastContinent = DataMgr::Instance()->getContinentAt(i)->name;
				
				// et on ouvre le nouveau
				ps->currentView = new ContinentView(DataMgr::Instance()->getContinentAt(i)->name);
				
				return true;
			}
		}
		
		if(event.GUIEvent.EventType == EGET_BUTTON_CLICKED)
		{
			if(event.GUIEvent.Caller->getID() == id_CountryBackButton)
			{
				CountryView* cv = dynamic_cast<CountryView*>(ps->currentView);
				
				// "logiquement" impossible
				if(!cv)
					throw MyException("Erreur de cast interne", __FILE__, __LINE__);
				
				// c'est pour nous.
				delete ps->currentView;
				ps->currentView = 0;
				
				// on nettoie
				StateMgr::Instance()->getSceneMgr()->clear();
				StateMgr::Instance()->getGuiEnv()->clear();
				
				// et on ouvre le nouveau
				ps->currentView = new ContinentView(lastContinent);
				
				return true;
				
			}
		}
	}
	
	
	if(event.EventType == EET_MOUSE_INPUT_EVENT)
	{
		if(event.MouseInput.Event == EMIE_MOUSE_MOVED)
		{
			if(mouse_down)
			{
				click = false;
				
				ContinentView* cv = dynamic_cast<ContinentView*>(ps->currentView);
			
				if(cv)
				{
					core::rect<int> absrect = cv->getZoomMap()->getAbsolute();
				
					if(event.MouseInput.X < absrect.LowerRightCorner.X && event.MouseInput.Y < absrect.LowerRightCorner.Y)
					{
						// drag
					
						cv->getZoomMap()->Drag(MouseLeftDownX, MouseLeftDownY, event.MouseInput.X, event.MouseInput.Y);
						
						// très important !!!!
						MouseLeftDownX = event.MouseInput.X;
						MouseLeftDownY = event.MouseInput.Y;
						
						return true;
					}
				}
			}
		}
		
		// non factorisable, non deplacable
		if(event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
		{
			MouseLeftDownX = event.MouseInput.X;
			MouseLeftDownY = event.MouseInput.Y;
			mouse_down = true;
			
			click = true;
			
			return false;
		}
		
		// non factorisable, non deplacable
		if(event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP)
		{
			mouse_down = false;
			
			// on a eu un click souris (sans drag)
			if(click)
			{
				ContinentView* cv = dynamic_cast<ContinentView*>(ps->currentView);
				if(cv)
				{
					std::string nompays = cv->matchCountry(event.MouseInput.X, event.MouseInput.Y);
					if(nompays.compare("") != 0)
					{
						cout << "Click sur : " << nompays << endl;
						
						// on change de vue !
						// on passe en vue Pays.
						
						delete ps->currentView;
						ps->currentView = 0;
						
						// on nettoie
						StateMgr::Instance()->getSceneMgr()->clear();
						StateMgr::Instance()->getGuiEnv()->clear();
				
						// et on ouvre le nouveau
						ps->currentView = new CountryView(nompays);
						
						return true;
					}
				}
				
			}
			
			click = false;
			
			/*
			ContinentView* cv = dynamic_cast<ContinentView*>(ps->currentView);
			if(cv)
			{
				int x;
				int y;
				cv->getZoomMap()->ScreenToTexture(event.MouseInput.X, event.MouseInput.Y, &x, &y);
				cout << "xscr:" << event.MouseInput.X << ", ";
				cout << "yscr:" << event.MouseInput.Y << ", ";
				cout << "xtex:" << x << ", ";
				cout << "ytex:" << y << endl;
			}
			*/
			return false;
		}
		
		////////////
		// le zoom
		// non factorisable, non deplacable
		if(event.MouseInput.Event == EMIE_MOUSE_WHEEL && total_time >= 0.2f)
		{
			total_time = 0.0f;
			
			ContinentView* cv = dynamic_cast<ContinentView*>(ps->currentView);
			
			if(cv)
			{
				
				if(event.MouseInput.Wheel == -1)
					cv->getZoomMap()->ZoomOut();
				else
					cv->getZoomMap()->ZoomIn();
				
				return true;
			}
		}
		
	}
	
	// resize de la fenetre
	if(event.EventType == EET_USER_EVENT)
	{
		// hauteur : event.UserEvent.UserData1
		// largeur : event.UserEvent.UserData2
		
		ps->currentView->resize(event.UserEvent.UserData2, event.UserEvent.UserData1);
		
		return true;
	}
	
	return false;
}


void PlayState::enter()
{
	cout << "Data Loading ..." << endl;
	
	// on charge toute les données
	DataMgr::Instance()->load();
	
	cout << "Data Loaded" << endl;
	
	total_time = 0.0f;
	
	// TODO : Changer le continent par défaut
	lastContinent = "Europe";
	currentView = new ContinentView("Europe");
	
	// on s'enregistre comme callback
	StateMgr::Instance()->getEventReceiver()->addCallback(PlayStateCallBack);
}


void PlayState::exit()
{
	delete currentView;
	// TODO : se retirer des Callbacks
}


void PlayState::frame(float time)
{
	elapsed_time = time;
	total_time += elapsed_time;
	currentView->frame(time);
}


